package com.leihub.xlfiletools.html.service;

import com.leihub.xlfiletools.html.annotation.DisplayField;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lei
 * @version 1.0
 * @description: TODO
 * @date 2024/8/3 6:31
 */
@Service
public class TableDisplayService {

    // 获取水平表格数据的方法
    public <T> Map<String, List<List<String>>> getHorizontalTableData(List<T> dataList, String tableName) {
        Map<String, List<List<String>>> tableDataMap = new LinkedHashMap<>(); // 使用LinkedHashMap以保持顺序
        List<List<String>> tableData = new ArrayList<>();

        if (dataList.isEmpty()) {
            tableDataMap.put(tableName, tableData); // 如果为空，返回空表结构
            return tableDataMap;
        }

        try {
            Field[] fields = dataList.get(0).getClass().getDeclaredFields();

            // 过滤具有 @DisplayField 注解的字段，并按字段排序
            List<Field> displayFields = getDisplayFields(fields);

            // 添加字段名称行（表头）
            List<String> fieldNames = displayFields.stream()
                    .map(field -> field.getAnnotation(DisplayField.class).name())
                    .collect(Collectors.toList());
            tableData.add(fieldNames);

            // 添加数据行
            for (T obj : dataList) {
                List<String> row = new ArrayList<>();
                for (Field field : displayFields) {
                    field.setAccessible(true);
                    Object value = field.get(obj);
                    row.add(value != null ? value.toString() : "");
                }
                tableData.add(row);
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        tableDataMap.put(tableName, tableData); // 将表名和表数据存入Map
        return tableDataMap;
    }


    public <T> Map<String, List<List<String>>> getVerticalTableData(List<T> dataList, String groupingFieldName, String firstColumnName, boolean useGroupingField) {
        Map<String, List<List<String>>> tableDataMap = new LinkedHashMap<>();
        if (dataList.isEmpty()) {
            return tableDataMap;
        }

        try {
            // 获取表头信息
            Field[] fields = dataList.get(0).getClass().getDeclaredFields();
            List<Field> displayFields = getDisplayFields(fields);

            // 定义分组数据
            Map<String, List<T>> groupedData;

            // 判断是否使用分组字段进行分组
            if (useGroupingField) {
                // 获取分组字段
                Field groupingField = Arrays.stream(fields)
                        .filter(field -> field.getName().equals(groupingFieldName))
                        .findFirst()
                        .orElseThrow(() -> new IllegalArgumentException("Invalid grouping field: " + groupingFieldName));
                groupingField.setAccessible(true);

                // 按分组字段分组数据
                groupedData = dataList.stream().collect(Collectors.groupingBy(obj -> {
                    try {
                        return groupingField.get(obj).toString();
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }));
            } else {
                // 如果不使用分组字段，则将所有数据作为一个组
                groupedData = new LinkedHashMap<>();
                groupedData.put("All Data", dataList);
            }

            for (Map.Entry<String, List<T>> entry : groupedData.entrySet()) {
                // 设置表名为tranCode的名字
                String groupName = entry.getKey();
                List<T> groupItems = entry.getValue();

                List<List<String>> tableData = new ArrayList<>();

                // 获取表头信息，确定最大列数（最大组内字段数 + 1）
                int maxColumnCount = displayFields.stream()
                        .collect(Collectors.groupingBy(field -> field.getAnnotation(DisplayField.class).groupName()))
                        .values().stream().mapToInt(List::size).max().orElse(0) + 1;

                List<String> headers = new ArrayList<>();
                headers.add(firstColumnName);
                displayFields.stream().limit(maxColumnCount - 1).forEach(field -> headers.add(field.getAnnotation(DisplayField.class).name()));
                tableData.add(headers);

                // 对每个对象进行分组显示
                Map<String, List<Field>> groupedFields = displayFields.stream()
                        .collect(Collectors.groupingBy(
                                field -> field.getAnnotation(DisplayField.class).groupName(),
                                LinkedHashMap::new,
                                Collectors.toList()));

                // 按组名排序并添加行数据
                groupedFields.entrySet().stream()
                        .sorted(Map.Entry.comparingByKey()) // 根据组名排序
                        .forEach(groupEntry -> {
                            String displayGroupName = groupEntry.getKey();
                            List<Field> groupFields = groupEntry.getValue();

                            // 每组的行
                            List<String> row = new ArrayList<>();
                            row.add(displayGroupName); // 添加组名

                            // 初始化这一行所有字段的值为空字符串
                            for (int i = 0; i < maxColumnCount - 1; i++) {
                                row.add("");
                            }

                            // 填充组内字段的值
                            for (int i = 0; i < groupFields.size(); i++) {
                                Field field = groupFields.get(i);
                                field.setAccessible(true);
                                try {
                                    Object value = field.get(groupItems.get(0));
                                    String fieldValue = value != null ? value.toString() : "";
                                    row.set(i + 1, fieldValue); // 根据表头索引填充对应的值
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                }
                            }
                            tableData.add(row);
                        });

                tableDataMap.put(groupName, tableData);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataMap;
    }


    // 辅助方法，用于过滤和排序具有 @DisplayField 注解的字段
    private List<Field> getDisplayFields(Field[] fields) {
        return Arrays.stream(fields)
                .filter(field -> field.isAnnotationPresent(DisplayField.class))
                .sorted(Comparator.comparingInt(field -> field.getAnnotation(DisplayField.class).group()))
                .collect(Collectors.toList());
    }



    public <T> Map<String, List<List<String>>> getVerticalTableData111(List<T> dataList, String tableName) {
        Map<String, List<List<String>>> tableDataMap = new LinkedHashMap<>();
        if (dataList.isEmpty()) {
            return tableDataMap;
        }

        try {
            // 获取表头信息
            Field[] fields = dataList.get(0).getClass().getDeclaredFields();
            List<Field> displayFields = getDisplayFields(fields);

            // 添加字段名称行（表头）
            List<String> headers = new ArrayList<>();
            for (Field field : displayFields) {
                headers.add(field.getAnnotation(DisplayField.class).name());
            }

            List<List<String>> tableData = new ArrayList<>();
            tableData.add(headers);

            // 将每个对象转换为一行数据
            for (T obj : dataList) {
                List<String> row = new ArrayList<>();
                for (Field field : displayFields) {
                    field.setAccessible(true);
                    Object value = field.get(obj);
                    row.add(value != null ? value.toString() : "");
                }
                tableData.add(row);
            }

            tableDataMap.put(tableName, tableData); // 使用自定义的表名

        } catch (Exception e) {
            e.printStackTrace();
        }
        return tableDataMap;
    }


}
